home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)ident.c 1.3 9/24/87
- */
- #include <stdio.h>
- #include "ident.h"
- #include "assert.h"
-
- #define CASEFOLD
-
- char *malloc();
-
- #define PAGESIZE 1024
- #define identsPerBlock (PAGESIZE)
- #define charsPerBlock PAGESIZE
-
- #define maxIdentElementBlocks 8
-
- typedef struct identElementStruct {
- Ident this;
- char *name;
- struct identElementStruct *next;
- } IdentElement;
-
- typedef IdentElement IdentElementBlock[identsPerBlock];
- typedef int HashResultType;
-
- static Ident nextIdentToAllocate = 0;
- static char *fillPtr, *fillBase;
-
- static IdentElementBlock *identElementBlockList[maxIdentElementBlocks];
-
- static char hashvalues[128] =
- {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 36, -1, 37, -1, -1, 38, -1,
- -1, -1, 39, 40, -1, 41, -1, 42,
- 26, 27, 28, 29, 30, 31, 32, 33,
- 34, 35, -1, -1, 43, 44, 45, 46,
- 47, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, -1, -1, -1, 48, 49,
- -1, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, -1, 50, -1, 51, -1
- };
-
- #define Value(x) ((int) hashvalues[x])
-
- static HashResultType Hash (tokenText)
- register char *tokenText;
- {
- #define R 52
- register int result;
- register int next;
- next = *tokenText++;
- result = Value(next);
- result = result * R;
- if (*tokenText != '\0') {
- next = *tokenText++;
- result = result + Value(next);
- }
- result = result * R;
- if (*tokenText != '\0') {
- next = *tokenText;
- result = result + Value(next);
- }
- return(result);
- }
- static IdentElement *hashTable[256];
-
- Ident Ident_Lookup(tokenText, tokenLength)
- char *tokenText;
- int tokenLength;
- {
- HashResultType x = Hash(tokenText);
- #ifdef CASEFOLD
- register char *l, *r;
- #endif
- register IdentElement *leader = hashTable[x % 256];
- register IdentElement *follower = NULL;
- register int compareResult;
- register Ident resultIdent = Ident_nil;
- IdentElementBlock **ieb;
- register IdentElement *ie;
-
- while (leader != NULL) {
- #ifdef CASEFOLD
- for (l = tokenText, r = leader->name; *l && *r; l++, r++) {
- compareResult = ((*l) & ~0x20) - ((*r) & ~ 0x20);
- if (compareResult) break;
- }
- if (compareResult == 0) compareResult = *l - *r;
- #else
- compareResult = strcmp(tokenText, leader->name);
- #endif
- if (compareResult == 0) {
- resultIdent = leader->this;
- break;
- } else if (compareResult < 0) {
- break;
- } else {
- follower = leader;
- leader = leader->next;
- }
- }
- if (resultIdent == Ident_nil) {
- resultIdent = nextIdentToAllocate;
- nextIdentToAllocate = nextIdentToAllocate + 1;
- ieb = &identElementBlockList[resultIdent / identsPerBlock];
- if (*ieb == NULL) {
- *ieb = (IdentElementBlock *) malloc(sizeof(IdentElementBlock));
- }
- ie = &((**ieb)[resultIdent % identsPerBlock]);
- if (tokenLength + 1 > charsPerBlock - (fillPtr - fillBase)) {
- fillBase = malloc(charsPerBlock);
- fillPtr = fillBase;
- }
- ie->name = fillPtr;
- #ifdef CASEFOLD
- for (l = fillPtr, r = tokenText; *r; l++, r++) {
- if (*r >= 'A' && *r <= 'Z') *l = *r - 'A' + 'a';
- else *l = *r;
- }
- *l = '\0';
- #else
- bcopy(tokenText, fillPtr, tokenLength + 1);
- #endif CASEFOLD
- fillPtr = fillPtr + tokenLength + 1;
- ie->this = resultIdent;
- ie->next = leader;
- if (follower == NULL) {
- hashTable[x % 256] = ie;
- } else {
- follower->next = ie;
- }
- }
- return (resultIdent);
- }
-
- void Ident_Initialize()
- {
- bzero((char *)hashTable, sizeof(hashTable));
- bzero((char *)identElementBlockList, sizeof(identElementBlockList));
- fillBase = (char *) malloc(charsPerBlock);
- fillPtr = fillBase;
- }
-
- char *Ident_Name(fIdent)
- Ident fIdent;
- {
- register IdentElementBlock *ibp;
- if (fIdent == -1) return ("<unknown>");
- else {
- ibp = identElementBlockList[fIdent / identsPerBlock];
- if (ibp == NULL) return(NULL);
- else return ((*ibp)[fIdent % identsPerBlock].name);
- }
- }
-